<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram - Rotating Frame</title>
</head>
<body>
    <canvas id="physicsCanvas" width="500" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Set background to white
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // Drawing properties
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 2;
        ctx.font = 'italic 22px "Times New Roman"';

        // Center point
        const cx = 250;
        const cy = 270;

        // Parameters to match the diagram's perspective and layout
        const axisLen = 170;
        const zAxisLen = 160;
        const bugDist = 110;
        const rotAngleDeg = 40; // Represents the angle ωt
        const rotAngleRad = rotAngleDeg * Math.PI / 180;

        // Angles for the axes in radians, chosen to match the diagram's perspective
        const y0AngleRad = -12 * Math.PI / 180;
        const x0AngleRad = 205 * Math.PI / 180;

        const yAngleRad = y0AngleRad + rotAngleRad;
        const xAngleRad = x0AngleRad + rotAngleRad;

        // Helper function to draw a line with an arrowhead
        function drawArrow(ctx, fromx, fromy, tox, toy) {
            const headlen = 12; // length of head in pixels
            const dx = tox - fromx;
            const dy = toy - fromy;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // 1. Draw the elliptical path of the merry-go-round
        ctx.beginPath();
        ctx.ellipse(cx, cy, axisLen + 5, 50, 0, 0, 2 * Math.PI);
        ctx.stroke();

        // 2. Draw the coordinate axes
        // z-axis (shared by z0, z1)
        drawArrow(ctx, cx, cy, cx, cy - zAxisLen);
        // x0-axis (stationary frame)
        drawArrow(ctx, cx, cy, cx + axisLen * Math.cos(x0AngleRad), cy + axisLen * Math.sin(x0AngleRad));
        // y0-axis (stationary frame)
        drawArrow(ctx, cx, cy, cx + axisLen * Math.cos(y0AngleRad), cy + axisLen * Math.sin(y0AngleRad));
        // x-axis (rotating frame)
        drawArrow(ctx, cx, cy, cx + axisLen * Math.cos(xAngleRad), cy + axisLen * Math.sin(xAngleRad));
        // y-axis (rotating frame)
        drawArrow(ctx, cx, cy, cx + axisLen * Math.cos(yAngleRad), cy + axisLen * Math.sin(yAngleRad));

        // 3. Draw the line indicating the bug's position from the origin
        const bugX = cx + bugDist * Math.cos(xAngleRad);
        const bugY = cy + bugDist * Math.sin(xAngleRad);
        ctx.beginPath();
        ctx.moveTo(cx, cy);
        ctx.lineTo(bugX, bugY);
        ctx.stroke();

        // 4. Draw the angle arcs
        const arcRadius = 70;
        ctx.save();
        ctx.lineWidth = 1.5;
        // Angle arc between x0 and x axes
        ctx.beginPath();
        ctx.arc(cx, cy, arcRadius, x0AngleRad, xAngleRad);
        ctx.stroke();
        // Angle arc between y0 and y axes
        ctx.beginPath();
        ctx.arc(cx, cy, arcRadius, y0AngleRad, yAngleRad);
        ctx.stroke();
        ctx.restore();

        // 5. Draw the rotation indicator arrow for ω
        ctx.save();
        ctx.lineWidth = 1.5;
        const omegaArrowRadius = 25;
        const omegaArrowCenterY = cy - zAxisLen + 20;
        const startAngle = Math.PI * 1.3;
        const endAngle = Math.PI * 0.5;
        ctx.beginPath();
        ctx.arc(cx, omegaArrowCenterY, omegaArrowRadius, startAngle, endAngle);
        ctx.stroke();
        // Arrowhead for the rotation indicator
        const arrowTipX = cx + omegaArrowRadius * Math.cos(endAngle);
        const arrowTipY = omegaArrowCenterY + omegaArrowRadius * Math.sin(endAngle);
        const tangentAngle = endAngle + Math.PI / 2;
        const headlen = 8;
        ctx.beginPath();
        ctx.moveTo(arrowTipX, arrowTipY);
        ctx.lineTo(arrowTipX - headlen * Math.cos(tangentAngle - Math.PI / 6), arrowTipY - headlen * Math.sin(tangentAngle - Math.PI / 6));
        ctx.moveTo(arrowTipX, arrowTipY);
        ctx.lineTo(arrowTipX - headlen * Math.cos(tangentAngle + Math.PI / 6), arrowTipY - headlen * Math.sin(tangentAngle + Math.PI / 6));
        ctx.stroke();
        ctx.restore();

        // 6. Add all labels to the diagram
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // Axes labels
        ctx.fillText('z₁', cx - 18, cy - zAxisLen + 5);
        ctx.fillText('z₀', cx + 18, cy - zAxisLen + 5);
        ctx.fillText('x₀', cx + (axisLen + 25) * Math.cos(x0AngleRad), cy + (axisLen + 25) * Math.sin(x0AngleRad));
        ctx.fillText('y₀', cx + (axisLen + 25) * Math.cos(y0AngleRad), cy + (axisLen + 25) * Math.sin(y0AngleRad) + 5);
        ctx.fillText('x', cx + (axisLen + 20) * Math.cos(xAngleRad), cy + (axisLen + 20) * Math.sin(xAngleRad) + 10);
        ctx.fillText('y', cx + (axisLen + 15) * Math.cos(yAngleRad), cy + (axisLen + 15) * Math.sin(yAngleRad) - 10);

        // Bug mass label 'm'
        ctx.fillText('m', bugX + 20 * Math.cos(xAngleRad - Math.PI / 2), bugY + 20 * Math.sin(xAngleRad - Math.PI / 2));

        // Angle labels 'ωt'
        const angleLabelRadius = arcRadius - 15;
        const midAngle_x = (x0AngleRad + xAngleRad) / 2;
        ctx.fillText('ωt', cx + angleLabelRadius * Math.cos(midAngle_x), cy + angleLabelRadius * Math.sin(midAngle_x));
        const midAngle_y = (y0AngleRad + yAngleRad) / 2;
        ctx.fillText('ωt', cx + angleLabelRadius * Math.cos(midAngle_y), cy + angleLabelRadius * Math.sin(midAngle_y));

        // Angular velocity label 'ω'
        ctx.fillText('ω', cx + omegaArrowRadius + 20, omegaArrowCenterY);

        // Figure caption
        ctx.font = '20px "Times New Roman"';
        ctx.fillText('Fig. 1.75.', cx, canvas.height - 25);

    </script>
</body>
</html>